#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
IP识别中间件
自动获取客户端IP地址并生成用户标识符
"""

from flask import g, current_app, request
from functools import wraps
from typing import Optional
from ..utils.ip_utils import get_user_identity, get_ip_info


class IPIdentityMiddleware:
    """IP身份识别中间件"""
    
    def __init__(self, app=None):
        """
        初始化中间件
        
        Args:
            app: Flask应用实例
        """
        self.app = app
        if app is not None:
            self.init_app(app)
    
    def init_app(self, app):
        """
        初始化Flask应用
        
        Args:
            app: Flask应用实例
        """
        app.before_request(self.before_request)
        app.after_request(self.after_request)
        
        # 注册中间件到应用扩展
        if not hasattr(app, 'extensions'):
            app.extensions = {}
        app.extensions['ip_identity_middleware'] = self
    
    def before_request(self):
        """
        请求前处理：获取用户身份信息
        """
        try:
            # 获取用户身份信息
            user_id, user_ip = get_user_identity()
            
            # 存储到Flask的g对象中，供后续使用
            g.user_id = user_id
            g.user_ip = user_ip
            g.ip_info = get_ip_info(user_ip)
            
            # 记录IP识别日志（调试模式下）
            if current_app.debug:
                current_app.logger.debug(
                    f"IP中间件: 用户ID={user_id}, IP={user_ip}, "
                    f"路径={request.path}, 方法={request.method}"
                )
            
            # 记录新用户访问（生产环境）
            if not current_app.debug:
                current_app.logger.info(f"用户访问: {user_id} ({user_ip}) -> {request.path}")
                
        except Exception as e:
            # IP识别失败时使用默认值，不影响正常请求
            current_app.logger.error(f"IP中间件错误: {e}")
            g.user_id = "ip_000000000000"  # 默认用户ID
            g.user_ip = "127.0.0.1"        # 默认IP
            g.ip_info = {"error": str(e)}
    
    def after_request(self, response):
        """
        请求后处理：记录响应信息
        
        Args:
            response: Flask响应对象
            
        Returns:
            Flask响应对象
        """
        try:
            # 添加用户标识头（可选，用于调试）
            if current_app.debug and hasattr(g, 'user_id'):
                response.headers['X-User-ID'] = g.user_id
                response.headers['X-User-IP-Hash'] = g.user_id.replace('ip_', '')
            
            # 记录响应日志
            if hasattr(g, 'user_id') and hasattr(g, 'user_ip'):
                current_app.logger.debug(
                    f"响应: {g.user_id} ({g.user_ip}) <- "
                    f"{response.status_code} {request.path}"
                )
                
        except Exception as e:
            current_app.logger.error(f"响应处理错误: {e}")
        
        return response


def require_user_identity(f):
    """
    装饰器：确保用户身份信息可用
    
    Args:
        f: 被装饰的函数
        
    Returns:
        装饰后的函数
    """
    @wraps(f)
    def decorated_function(*args, **kwargs):
        # 检查用户身份信息是否可用
        if not hasattr(g, 'user_id') or not hasattr(g, 'user_ip'):
            current_app.logger.warning("用户身份信息不可用，尝试重新获取")
            try:
                user_id, user_ip = get_user_identity()
                g.user_id = user_id
                g.user_ip = user_ip
                g.ip_info = get_ip_info(user_ip)
            except Exception as e:
                current_app.logger.error(f"获取用户身份失败: {e}")
                # 使用默认值
                g.user_id = "ip_000000000000"
                g.user_ip = "127.0.0.1"
                g.ip_info = {"error": str(e)}
        
        return f(*args, **kwargs)
    
    return decorated_function


def get_current_user_id() -> str:
    """
    获取当前用户ID
    
    Returns:
        str: 当前用户的ID
    """
    if hasattr(g, 'user_id'):
        return g.user_id
    
    # 如果g对象中没有用户ID，尝试实时获取
    try:
        user_id, _ = get_user_identity()
        return user_id
    except Exception as e:
        current_app.logger.error(f"获取当前用户ID失败: {e}")
        return "ip_000000000000"


def get_current_user_ip() -> str:
    """
    获取当前用户IP
    
    Returns:
        str: 当前用户的IP地址
    """
    if hasattr(g, 'user_ip'):
        return g.user_ip
    
    # 如果g对象中没有用户IP，尝试实时获取
    try:
        _, user_ip = get_user_identity()
        return user_ip
    except Exception as e:
        current_app.logger.error(f"获取当前用户IP失败: {e}")
        return "127.0.0.1"


def get_current_user_info() -> dict:
    """
    获取当前用户的完整信息
    
    Returns:
        dict: 用户信息字典
    """
    return {
        'user_id': get_current_user_id(),
        'user_ip': get_current_user_ip(),
        'ip_info': getattr(g, 'ip_info', {}),
        'request_path': request.path if request else None,
        'request_method': request.method if request else None
    }
